define([
    'app',
    'json2',
    'jquery.format',
    'ace-language-tools'
], function(app, JSON2) {
    app.controller('EditMockDocController', function($scope, $compile, $timeout, xContext, $uibModalInstance,
            xUtil, toastr) {
        var self = this;
        self.typeName = '';
        self.parsable = true;
        self.fullScreen = false;

        var docEditor = null,
            formatter = null;

        self.init = function() {
            var modeType = 'text',
                data = xContext.editor.getValue(),
                docValue = '';
            if (xContext.type == 'headers') {
                self.typeName = 'Headers';
                formatter = getFormatter('json');
                modeType = 'hjson';
                docValue = xUtil.regex.keyMatch(data, 'Headers') || '{}';
            } else if (xContext.type == 'query') {
                self.typeName = 'Query';
                formatter = getFormatter('json');
                modeType = 'hjson';
                docValue = xUtil.regex.keyMatch(data, 'Query') || '{}';
            } else if (xContext.type == 'parameters') {
                self.typeName = '入参';
                if (xContext.extname == '.json') {
                    modeType = 'hjson';
                    formatter = getFormatter('json');
                } else if (xContext.extname == '.xml') {
                    modeType = 'xml';
                    formatter = getFormatter('xml');
                }
                docValue = xUtil.regex.keyMatch(data, '入参');
            } else if (xContext.type == 'comments') {
                self.typeName = '备注';
                formatter = getFormatter('text');
                docValue = xUtil.regex.keyMatch(data, '备注');
            }

            // Document editor
            docEditor = ace.edit('doc-editor', {
                mode: 'ace/mode/' + modeType,
                theme: 'ace/theme/chrome',
                fontSize: xContext.editor.getFontSize(),
                wrap: xContext.editor.getOption('wrap'),
                showPrintMargin: false,
                autoScrollEditorIntoView: true,
                enableBasicAutocompletion: true,
                enableSnippets: true,
                enableLiveAutocompletion: true,
                tooltipOffset: function() {
                    return $(docEditor.container).parents('.modal-dialog').offset();
                }
            });
            docEditor.getSession().on('changeAnnotation', function(e) {
                // Check errors
                $timeout(function() {
                    var annotations = docEditor.getSession().getAnnotations();
                    var parsable = true;
                    if (!_.isEmpty(annotations)) {
                        if (_.find(annotations, function(annotation) {
                            return annotation.type == 'error';
                        })) {
                            parsable = false;
                        }
                    }
                    if (self.parsable != parsable) {
                        self.parsable = parsable;
                    }
                });
            });


            $('#doc-editor .ace_scroller').append(
                    $compile($('#doc-editor-tools').html())($scope)
                );
            $('#doc-editor .x-editor-tool').mousedown(function(e) { return false; });

            $scope.$watch('dvm.fullScreen', function(fullScreen) {
                if (fullScreen) {
                    $('.modal-dialog:eq(0)').toggleClass('x-modal-max');
                } else {
                    $('.modal-dialog:eq(0)').removeClass('x-modal-max');
                }
                setTimeout(function() {
                    docEditor.resize();
                }, 50);
            });

            $timeout(function() {
                docEditor.setValue(docValue.trim(), -1);
                docEditor.resize();
            });
        }

        self.ok = function(valid) {
            if (valid) {
                if (xContext.extname == '.json') {
                    if (/\/\*|\*\//gm.test(docEditor.getValue())) {
                        toastr.error('文本内容中不可包含/*或*/字符！');
                        return;
                    }
                } else if (xContext.extname == '.xml') {
                    if (/\<\!--|--\>/gm.test(docEditor.getValue())) {
                        toastr.error('文本内容中不可包含<!--或-->字符！');
                        return;
                    }
                }

                var docValue = xContext.editor.getValue();
                if (xContext.type == 'headers') {
                    docValue = docValue.replace(/^@Headers：\n?(((?!\n@)[^])*)\n@/gmi, function(whole, match) {
                        return '@Headers：\n' + docEditor.getValue().trim() + '\n@';
                    });
                } else if (xContext.type == 'query') {
                    docValue = docValue.replace(/^@Query：\n?(((?!\n@)[^])*)\n@/gm, function(whole, match) {
                        return '@Query：\n' + docEditor.getValue().trim() + '\n@';
                    });
                } else if (xContext.type == 'parameters') {
                    docValue = docValue.replace(/^@入参：\n?(((?!\n@)[^])*)\n@/gm, function(whole, match) {
                        return '@入参：\n' + docEditor.getValue().trim() + '\n@';
                    });
                } else if (xContext.type == 'comments') {
                    docValue = docValue.replace(/^@备注：\n?(((?!\n@)[^])*)\n@/gm, function(whole, match) {
                        return '@备注：\n' + docEditor.getValue().trim() + '\n@';
                    });
                }
                xContext.editor.setValue(docValue, -1);
                xContext.editor.resize();
                xContext.editor.focus();
                $uibModalInstance.close(true);
            }
        }

        var formattedCode = '';
        self.format = function() {
            if (docEditor.getValue() != formattedCode) {
                formattedCode = formatter(docEditor.getValue()).trim();
                docEditor.setValue(formattedCode, -1);
                docEditor.resize();
            }
            toastr.success('文本内容已格式化！');
        }

        function getFormatter(type) {
            switch (type) {
                case 'json':
                    return function(text) {
                        return JSON2.format(text, '    ');
                    };
                case 'xml':
                    return function(text) {
                        return $.format(text, { method: 'xml' });
                    };
                default:
                    return function(text) {
                        return text;
                    };
            }
        }

        self.cancel = function() {
            $uibModalInstance.dismiss();
        }
    });
});
